package com.fly.show.api;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Data;

/**
 * 
 * RestUrlController
 * 
 * @author 00fly
 * @version [版本号, 2020-04-16]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Api(tags = "控制器数据接口")
@RestController
@ConditionalOnWebApplication
public class RestUrlController
{
    @Autowired
    RequestMappingHandlerMapping mapping;
    
    @ApiOperation("获取URL")
    @GetMapping("/getAllUrl")
    public List<String> getAllUrl()
    {
        Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
        List<String> urlList = new ArrayList<>();
        for (RequestMappingInfo info : map.keySet())
        {
            Set<String> patterns = info.getPatternsCondition().getPatterns();
            for (String url : patterns)
            {
                urlList.add(url);
            }
        }
        return urlList;
    }
    
    @ApiOperation("获取urlInfos")
    @GetMapping("/urlInfos")
    public List<URLInfo> urlInfos()
    {
        // Stream.filter
        List<URLInfo> urlList = getAllURLInfo().stream().filter(url -> url.getClassName().startsWith("com.fly") && "GET".equals(url.getType())).collect(Collectors.toList());
        return urlList;
    }
    
    private List<URLInfo> getAllURLInfo()
    {
        List<URLInfo> urlList = new ArrayList<>();
        Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> m : map.entrySet())
        {
            URLInfo urlInfo = new URLInfo();
            RequestMappingInfo info = m.getKey();
            HandlerMethod method = m.getValue();
            PatternsRequestCondition p = info.getPatternsCondition();
            for (String url : p.getPatterns())
            {
                urlInfo.getUrl().add(url);
            }
            urlInfo.setClassName(method.getMethod().getDeclaringClass().getName());
            urlInfo.setMethod(method.getMethod().getName());
            RequestMethodsRequestCondition methodsCondition = info.getMethodsCondition();
            String type = methodsCondition.toString();
            if (type != null && type.startsWith("[") && type.endsWith("]"))
            {
                type = type.substring(1, type.length() - 1);
                urlInfo.setType(type);
            }
            urlList.add(urlInfo);
        }
        return urlList;
    }
}

@Data
class URLInfo
{
    private List<String> url = new ArrayList<>();
    
    private String method;
    
    private String type;
    
    private String className;
}